<script setup lang="ts">
import { ref, computed } from 'vue'

const { mode, animated, unit } = defineProps({
  mode: {
    type: String,
    validator: (value) => ['horizontal', 'vertical'].includes(value),
    default: 'horizontal',
  },
  modelValue: {
    type: [Number, String],
    default: 0.5,
  },
  min: {
    type: [Number, String],
    default: '40px',
  },
  max: {
    type: [Number, String],
    default: '40px',
  },
  unit: {
    type: String,
    default: 'percent',
    validator: (value) => ['px', 'percent'].includes(value),
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  showTriggerOnDisabled: {
    type: Boolean,
    default: true,
  },
  responsive: {
    type: Boolean,
    default: true,
  },
  animated: {
    type: Boolean,
    default: false,
  },
})
const emit = defineEmits(['update:modelValue', 'on-move-start', 'on-moving', 'on-move-end'])
const name = ref('cw-split')
const moving = ref(false)
const isHorizontal = computed(() => mode === 'horizontal')
const wrapperClass = computed(() => [`${name.value}-wrapper`, moving.value ? 'no-select' : ''])
const paneClass = computed(() => [
  `${name.value}-pane`,
  moving.value ? `${name.value}-pane-moving` : '',
])
const animatedClass = computed(() => (animated && !moving.value ? 'animated-pane' : ''))
const left = ref(40)
const right = computed(() => {
  const size = 'string' == typeof left.value ? parseFloat(left.value) : left.value
  return 'px' === unit ? `calc(100% - ${size}px)` : 100 - size + '%'
})
</script>

<template>
  <div :class="wrapperClass">
    <div v-if="isHorizontal" :class="`${name}-horizontal`">
      <div :class="['left-pane', [paneClass, animatedClass]]" :style="{ right }">
        <slot name="left"></slot>
      </div>
      <div
        :class="`${name}-trigger-con`"
        :style="{ left }"
        v-show="showTriggerOnDisabled || !disabled"
      >
        <slot name="trigger">
          <div :class="`${name}-trigger-vertical${disabled ? '-disabled' : ''}`"></div>
        </slot>
      </div>
      <div :class="['right-pane', [paneClass, animatedClass]]" :style="{ left }">
        <slot name="right"></slot>
      </div>
    </div>
    <div v-else :class="`${name}-vertical`">
      <div :class="['top-pane', [paneClass, animatedClass]]" :style="{ bottom: right }">
        <slot name="top"></slot>
      </div>
      <div
        :class="`${name}-trigger-con`"
        :style="{ top: left }"
        v-show="showTriggerOnDisabled || !disabled"
      >
        <slot name="trigger">
          <div :class="`${name}-trigger-horizontal${disabled ? '-disabled' : ''}`"></div>
        </slot>
      </div>
      <div :class="['bottom-pane', [paneClass, animatedClass]]" :style="{ top: left }">
        <slot name="bottom"></slot>
      </div>
    </div>
  </div>
</template>

<style scoped>
.cw-split-wrapper {
  height: 100%;
  position: relative;
  width: 100%;
}

.cw-split-pane {
  position: absolute;
}

.cw-split-pane.left-pane,
.cw-split-pane.right-pane {
  bottom: 0;
  top: 0;
}

.cw-split-pane.left-pane {
  left: 0;
}

.cw-split-pane.right-pane {
  right: 0;
}

.cw-split-pane.bottom-pane,
.cw-split-pane.top-pane {
  left: 0;
  right: 0;
}

.cw-split-pane.top-pane {
  top: 0;
}

.cw-split-pane.bottom-pane {
  bottom: 0;
}

.cw-split-pane-moving {
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

.cw-split-trigger-con {
  position: absolute;
  transform: translate(-50%, -50%);
  z-index: 10;
}

.cw-split-horizontal > .cw-split-trigger-con {
  height: 100%;
  top: 50%;
  width: 0;
  z-index: 11;
}

.cw-split-vertical > .cw-split-trigger-con {
  height: 0;
  left: 50%;
  width: 100%;
  z-index: 11;
}

.no-select {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

.cw-split-trigger-horizontal-disabled,
.cw-split-trigger-horizontal {
  border-top: var(--border-width-base) solid var(--designer-border-color);
  height: var(--designer-trigger-width);
  width: 100%;
}

.cw-split-trigger-horizontal {
  cursor: row-resize;
}

.cw-split-trigger-horizontal:hover {
  border-top: 2px solid var(--primary-color);
}

.cw-split-trigger-vertical-disabled,
.cw-split-trigger-vertical {
  border-left: var(--border-width-base) solid var(--designer-border-color);
  height: 100%;
  width: var(--designer-trigger-width);
}

.cw-split-trigger-vertical {
  cursor: col-resize;
}

.cw-split-trigger-vertical:hover {
  border-left: 2px solid var(--primary-color);
}

.animated-pane {
  transition: 0.3s cubic-bezier(0.6, 0.6, 0, 1);
}
</style>
